#ifndef VIEWMODEL_H
#define VIEWMODEL_H

#include <QObject>
#include "vmsearchresult.h"
#include "onesearchresult.h"
#include <QDeclarativeItem>
#include <QMetaObject>
#include <QAction>
#include "shareddir.h"

namespace dcpp {
    class Client;
}

// Создам перечиление в Qt-ешной обвязке.
/** Основные разделы рограммы. */
class Pages : public QDeclarativeItem{
    Q_OBJECT
    Q_ENUMS(PagesEnum)
public:
    enum PagesEnum{
        media,
        search,
        uploads,
        chat,
        hubs
    };
    /** Получить метаобъект перечисления. @see QMetaEnum */
    static inline const QMetaEnum m(){
        const QMetaObject &mo = Pages::staticMetaObject;
        return mo.enumerator(mo.indexOfEnumerator("PagesEnum"));
    }
};

class MyProgramm;
typedef QList<SharedDir*> SharedDirList;

/** Модель данных отображаемых пользователю
 *
 * @author Василий Почкаенко.
 */
class ViewModel : public QObject{
    Q_OBJECT

    /** Раздел программы активный в настоящий момент..*/
    Q_PROPERTY(Pages::PagesEnum page READ page WRITE setPage NOTIFY pageChange)
    /** Раздел программы активный в настоящий момент.*/
    Q_PROPERTY(QString pageName READ pageName NOTIFY pageChange)
    /** Список хабов.*/
    Q_PROPERTY(QList<QObject*> hubs READ hubs NOTIFY hubsChange)

    /** Основной хаб.*/
    Q_PROPERTY(QObject * mainHub READ mainHub NOTIFY mainHubChange)

    /** Адрес медиасервиса.*/
    Q_PROPERTY(QString mediaURL READ mediaURL WRITE setMediaURL NOTIFY mediaURLChange)
    /** Адрес регистрации на медиасервисе.*/
    Q_PROPERTY(QString registrationURL READ registrationURL WRITE setRegistrationURL NOTIFY registrationURLChange)
    /** Адрес файла помощи.*/
    Q_PROPERTY(QString helpURL READ helpURL WRITE setHelpURL NOTIFY helpURLChange)
    /** Тип соединения.
     *
     * Активный – прямое соединение, кабель вставлен в компьютер.
     * Пассивный режим – не рекомендуемый тип подключения. Файрвол
     * с UPnP - поддерживается не всеми роутерами, обычно требуется
     * включение данной функции, подробнее см. на сайте. Файрвол с
     * ручным перенаправление портов – требуется настройка роутера,
     * см. на сайте. IP необходимо автоматически определить, по
     * запросу к серверу.*/
    Q_PROPERTY(int connectionType READ connectionType WRITE setConnectionType NOTIFY connectionTypeChange)
    /** Строка поискового запроса.*/
    Q_PROPERTY(QString searchStr READ searchStr WRITE setSearchStr NOTIFY searchStrChange)
    /** Размер искомого файла.*/
    Q_PROPERTY(int searchFileSize READ searchFileSize WRITE setSearchFileSize NOTIFY searchFileSizeChange)
    /** Тип искомого файла.*/
    Q_PROPERTY(QString searchFileType READ searchFileType WRITE setSearchFileType NOTIFY searchFileTypeChange)
    /** .*/
    Q_PROPERTY(QList<VMSearchResult *> searchResult READ searchResult NOTIFY searchResultChange)
    /** Список раздаваемых файлов.*/
    Q_PROPERTY(QList<QObject *> uploadsList READ uploadsList NOTIFY uploadsListChange)
    /** Список загружаемых файлов.*/
    Q_PROPERTY(QList<QObject *> downloudsList READ downloudsList NOTIFY downloudsListChange)
    /** Список загруженых файлов.*/
    Q_PROPERTY(QList<QObject *> downloudedList READ downloudedList NOTIFY downloudedListChange)
    /** Электроная почта пользователя.*/
    Q_PROPERTY(QString userEmail READ userEmail WRITE setUserEmail NOTIFY userEmailChange)
    /** Список расшаренных папок.*/
    Q_PROPERTY(SharedDirList sharedDirs READ sharedDirs NOTIFY sharedDirsChange)

    /** Действие: Перейти на вкладку "портал".*/
    Q_PROPERTY( QAction * mediaPage READ mediaPage NOTIFY actionsChange)
    /** Действие: Перейти на вкладку "поиск".*/
    Q_PROPERTY( QAction * searchPage READ searchPage NOTIFY actionsChange)
    /** Действие: Перейти на вкладку "раздачи".*/
    Q_PROPERTY( QAction * uploadsPage READ uploadsPage NOTIFY actionsChange)
    /** Действие: Перейти на вкладку "общение".*/
    Q_PROPERTY( QAction * chatPage READ chatPage NOTIFY actionsChange)
    /** Действие: Перейти на вкладку "хабы".*/
    Q_PROPERTY( QAction * hubsPage READ hubsPage NOTIFY actionsChange)
    /** Действие: Выйти.*/
    Q_PROPERTY(QAction * exit READ exit NOTIFY actionsChange)
    /** Действие: сверуть.*/
    Q_PROPERTY(QAction * minimize READ minimize NOTIFY actionsChange)
    /** Действие: открыть настройки.*/
    Q_PROPERTY(QAction * settings READ settings NOTIFY settingsChange)

private:
    /** Раздел программы активный в настоящий момент..*/
    Pages::PagesEnum m_page;
    /** Адрес медиасервиса.*/
    QString m_mediaURL;
    /** Адрес регистрации на медиасервисе.*/
    QString m_registrationURL;
    /** Адрес файла помощи.*/
    QString m_helpURL;
    /** Строка поискового запроса.*/
    QString m_searchStr;
    /** Размер искомого файла.*/
    int m_searchFileSize;
    /** Тип искомого файла.*/
    QString m_searchFileType;
    /** Список результатов для всех поисковых запросов.*/
    QList<VMSearchResult *> m_searchResult;
    /** Список раздаваемых файлов.*/
    QList<QObject *> m_uploadsList;
    /** Список загружаемых файлов.*/
    QList<QObject *> m_downloudsList;
    /** Список загруженых файлов.*/
    QList<QObject *> m_downloudedList;
    /** Список хабов*/
    QList<QObject*> m_hubs;
    /** Электроная почта пользователя.*/
    QString m_userEmail;

    SharedDirList m_sharedDirList_buf;
    MyProgramm * m_prog;
private slots:
    void goToMediaPage();
    void goToSearchPage();
    void goToUploadsPage();
    void goToChatPage();
    void goToHubsPage();
public:
    explicit ViewModel(MyProgramm *parent);

    /** Раздел программы активный в настоящий момент..*/
    Pages::PagesEnum page() const;
    /** Раздел программы активный в настоящий момент.*/
    QString pageName() const;
    /** Изменить раздел программы активный в настоящий момент..*/
    void setPage(const Pages::PagesEnum page);
    /** Адрес медиасервиса.*/
    QString mediaURL() const;
    /** Изменить адрес медиасервиса.*/
    void setMediaURL(const QString & mediaURL);
    /** Адрес регистрации на медиасервисе.*/
    QString registrationURL() const;
    /** Установить адрес регистрации на медиасервисе.*/
    void setRegistrationURL(const QString & registrationURL);
    /** Адрес файла помощи.*/
    QString helpURL() const;
    /** Изменить адрес файла помощи.*/
    void setHelpURL(const QString & helpURL);
    /** Тип соединения.
     *
     * Активный – прямое соединение, кабель вставлен в компьютер.
     * Пассивный режим – не рекомендуемый тип подключения. Файрвол
     * с UPnP - поддерживается не всеми роутерами, обычно требуется
     * включение данной функции, подробнее см. на сайте. Файрвол с
     * ручным перенаправление портов – требуется настройка роутера,
     * см. на сайте. IP необходимо автоматически определить, по
     * запросу к серверу.*/
    int connectionType() const;
    /** Изменить Тип соединения.*/
    void setConnectionType(int connectionType);
    /** Строка поискового запроса.*/
    QString searchStr() const;
    /** Изменить строку поискового запроса.*/
    void setSearchStr(const QString & searchStr);
    /** Размер искомого файла.*/
    int searchFileSize() const;
    /** Изменить размер искомого файла.*/
    void setSearchFileSize(const int searchFileSize);
    /** Тип искомого файла.*/
    QString searchFileType() const;
    /** Изменить тип искомого файла.*/
    void setSearchFileType(const QString & searchFileType);
    /** Список результатов для всех поисковых запросов.*/
    QList<VMSearchResult *> searchResult() const;
    /** Список раздаваемых файлов.*/
    QList<QObject *> uploadsList() const;
    /** Список загружаемых файлов.*/
    QList<QObject *> downloudsList() const;
    /** Список загруженых файлов.*/
    QList<QObject *> downloudedList() const;    
    /** Электронная почта пользователя.*/
    const QString & userEmail() const;
    /** Установить электронную почту пользователя.*/
    void setUserEmail(const QString & userEmail);
    /** Список расшаренных папок.*/
    QList<SharedDir *> & sharedDirs();

    /** Перейти на вкладку "портал".*/
    QAction *mediaPage() const;
    /** Перейти на вкладку "хабы".*/
    QAction *hubsPage() const;
    /** Перейти на вкладку "общение".*/
    QAction *chatPage() const;
    /** Перейти на вкладку "раздачи".*/
    QAction * uploadsPage() const;
    /** Перейти на вкладку "поиск".*/
    QAction *searchPage() const;
    /** Действие: Выйти.*/
    QAction * exit() const;
    /** Действие: сверуть.*/
    QAction * minimize() const;
    /** Действие: открыть настройки.*/
    QAction *settings() const;

    /** Основной хаб.*/
    QObject * mainHub() const;
    /** Список хабов.*/
    const QList<QObject*> & hubs() const;

public slots:
    void addedNewHub(dcpp::Client * client);
signals:
    /** Изменился раздел программы активный в настоящий момент..*/
    void pageChange();
    /** Изменился адрес медиасервиса.*/
    void mediaURLChange();
    /** Изменился адрес регистрации на медиасервисе.*/
    void registrationURLChange();
    /** Изменился адрес файла помощи.*/
    void helpURLChange();
    /** Изменилось тип соединения.*/
    void connectionTypeChange();
    /** Изменилась строка поискового запроса.*/
    void searchStrChange();
    /** Изменился размер искомого файла.*/
    void searchFileSizeChange();
    /** Изменился тип искомого файла.*/
    void searchFileTypeChange();
    /** Изменился список результатов для всех поисковых запросов.*/
    void searchResultChange();
    /** Изменился список раздаваемых файлов.*/
    void uploadsListChange();
    /** Изменилось Список загружаемых файлов.*/
    void downloudsListChange();
    /** Изменился список загруженых файлов.*/
    void downloudedListChange();
    void actionsChange();
    /** Изменился Основной хаб.*/
    void mainHubChange();
    /** Изменился Список хабов.*/
    void hubsChange();
    /** Изменилась электроная почта пользователя.*/
    void userEmailChange();
    /** Изменился список расшаренных папок.*/
    void sharedDirsChange();
    /** Изменилось Действие: открыть настройки.*/
    void settingsChange();

};

#endif // VIEWMODEL_H
